"""知识图谱API路由"""
from typing import List, Dict, Any, Optional
from fastapi import APIRouter, HTTPException, Query, Depends, Body
from pydantic import BaseModel
from src.services.service_wrappers import get_knowledge_graph_service

# 创建路由器
router = APIRouter(prefix="/knowledge-graph", tags=["知识图谱"])


class QueryRequest(BaseModel):
    """查询请求模型"""
    query: str
    limit: Optional[int] = 5

class StoreRequest(BaseModel):
    """存储请求模型"""
    text: str

class SemanticSearchRequest(BaseModel):
    """语义搜索请求模型"""
    query: str
    limit: Optional[int] = 3

class AutoBuildRequest(BaseModel):
    """自动构建请求模型"""
    data_source: str
    update_interval: Optional[int] = 3600

class CrossDomainFusionRequest(BaseModel):
    """跨领域融合请求模型"""
    domains: List[str]

class QueryResponse(BaseModel):
    """查询响应模型"""
    results: List[Dict[str, Any]]

class StoreResponse(BaseModel):
    """存储响应模型"""
    success: bool
    message: str

class HealthResponse(BaseModel):
    """健康检查响应模型"""
    neo4j_connected: bool
    embedding_ready: bool
    status: str


@router.post("/query", response_model=QueryResponse)
async def query_knowledge_graph(request: QueryRequest):
    """
    查询知识图谱
    
    Args:
        request: 查询请求体
        
    Returns:
        查询响应
    """
    try:
        kg_service = get_knowledge_graph_service()
        if kg_service is None:
            raise HTTPException(status_code=503, detail="知识图谱服务不可用")
        
        # 修复类型错误：当 request.limit 为 None 时，使用默认值 5
        limit = request.limit if request.limit is not None else 5
        results = kg_service.query_knowledge(request.query, limit)
        return {"results": results}
    except Exception as e:
        # 记录错误但不抛出异常，返回空结果
        import logging
        logging.error(f"知识图谱查询失败: {str(e)}")
        return {"results": []}


@router.post("/store", response_model=StoreResponse)
async def store_knowledge(request: StoreRequest):
    """
    存储知识到图谱
    
    Args:
        request: 存储请求体
        
    Returns:
        存储响应
    """
    try:
        kg_service = get_knowledge_graph_service()
        if kg_service is None:
            raise HTTPException(status_code=503, detail="知识图谱服务不可用")
        
        success = kg_service.store_knowledge(request.text)
        if success:
            return {"success": True, "message": "知识存储成功"}
        else:
            return {"success": False, "message": "知识存储失败"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"知识存储失败: {str(e)}")


@router.get("/search", response_model=QueryResponse)
async def hybrid_search(query: str, limit: int = 5):
    """
    混合搜索
    
    Args:
        query: 搜索查询
        limit: 结果限制数量
        
    Returns:
        混合搜索响应
    """
    try:
        kg_service = get_knowledge_graph_service()
        if kg_service is None:
            raise HTTPException(status_code=503, detail="知识图谱服务不可用")
        
        results = kg_service.hybrid_search(query, limit)
        return {"results": results}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"混合搜索失败: {str(e)}")


@router.post("/semantic-search", response_model=QueryResponse)
async def semantic_search(request: SemanticSearchRequest):
    """
    语义搜索
    
    Args:
        request: 语义搜索请求
        
    Returns:
        搜索响应
    """
    try:
        kg_service = get_knowledge_graph_service()
        if kg_service is None:
            raise HTTPException(status_code=503, detail="知识图谱服务不可用")
        
        # 修复类型错误：当 request.limit 为 None 时，使用默认值 3
        limit = request.limit if request.limit is not None else 3
        results = kg_service.semantic_search(request.query, limit)
        return {"results": results}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"语义搜索失败: {str(e)}")


@router.get("/health", response_model=HealthResponse)
async def health_check():
    """
    健康检查
    
    Returns:
        健康状态
    """
    try:
        kg_service = get_knowledge_graph_service()
        if kg_service is None:
            return {
                "neo4j_connected": False,
                "embedding_ready": False,
                "status": "unavailable"
            }
        
        neo4j_connected = kg_service.graph is not None
        embedding_ready = kg_service.embedding_model is not None
        status = "healthy" if neo4j_connected or embedding_ready else "degraded"
        
        return {
            "neo4j_connected": neo4j_connected,
            "embedding_ready": embedding_ready,
            "status": status
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"健康检查失败: {str(e)}")


@router.post("/auto-build")
async def auto_build_knowledge_graph(request: AutoBuildRequest):
    """
    自动构建知识图谱
    
    Args:
        request: 自动构建请求
        
    Returns:
        构建响应
    """
    try:
        kg_service = get_knowledge_graph_service()
        if kg_service is None:
            raise HTTPException(status_code=503, detail="知识图谱服务不可用")
        
        kg_service.auto_build_from_data_source(
            data_source=request.data_source,
            update_interval=request.update_interval or 3600
        )
        
        return {"success": True, "message": f"已启动自动构建任务: {request.data_source}"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"自动构建失败: {str(e)}")


@router.post("/incremental-update")
async def incremental_update(new_data: List[Dict[str, Any]] = Body(...)):
    """
    增量更新知识图谱
    
    Args:
        new_data: 新数据列表
        
    Returns:
        更新响应
    """
    try:
        kg_service = get_knowledge_graph_service()
        if kg_service is None:
            raise HTTPException(status_code=503, detail="知识图谱服务不可用")
        
        success = kg_service.incremental_update(new_data)
        if success:
            return {"success": True, "message": "增量更新成功"}
        else:
            return {"success": False, "message": "增量更新失败"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"增量更新失败: {str(e)}")


@router.post("/infer-relationships")
async def infer_new_relationships():
    """
    推理新的关系
    
    Returns:
        推理结果
    """
    try:
        kg_service = get_knowledge_graph_service()
        if kg_service is None:
            raise HTTPException(status_code=503, detail="知识图谱服务不可用")
        
        relationships = kg_service.infer_new_relationships()
        return {"relationships": relationships}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"关系推理失败: {str(e)}")


@router.post("/cross-domain-fusion")
async def cross_domain_knowledge_fusion(request: CrossDomainFusionRequest):
    """
    跨领域知识融合
    
    Args:
        request: 跨领域融合请求
        
    Returns:
        融合结果
    """
    try:
        kg_service = get_knowledge_graph_service()
        if kg_service is None:
            raise HTTPException(status_code=503, detail="知识图谱服务不可用")
        
        success = kg_service.cross_domain_knowledge_fusion(request.domains)
        if success:
            return {"success": True, "message": "跨领域知识融合成功"}
        else:
            return {"success": False, "message": "跨领域知识融合失败"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"跨领域知识融合失败: {str(e)}")